/**
 * @file IRGenerator.cpp
 * @author zenglj (zenglj@nwpu.edu.cn)
 * @brief AST遍历产生线性IR
 * @version 0.1
 * @date 2023-09-24
 *
 * @copyright Copyright (c) 2023
 *
 */
#include <cstdint>
#include <cstdio>
#include <unordered_map>
#include <vector>

#include "AST.h"
#include "IRCode.h"
#include "IRGenerator.h"
#include "IRInst.h"
#include "SymbolTable.h"
#include "Value.h"
#include "ValueType.h"

/// @brief 构造函数
/// @param _root AST的根
/// @param _symtab 符号表
IRGenerator::IRGenerator(ast_node * _root, SymbolTable * _symtab) : root(_root), symtab(_symtab)
{
    /* 叶子节点 */
    ast2ir_handlers[ast_operator_type::AST_OP_LEAF_LITERAL_INT] = &IRGenerator::ir_leaf_node_int;
    ast2ir_handlers[ast_operator_type::AST_OP_LEAF_LITERAL_FLOAT] = &IRGenerator::ir_leaf_node_float;
    ast2ir_handlers[ast_operator_type::AST_OP_LEAF_VAR_ID] = &IRGenerator::ir_leaf_node_var_id;

    /* 表达式运算， 加减 */
    ast2ir_handlers[ast_operator_type::AST_OP_SUB] = &IRGenerator::ir_sub;
    ast2ir_handlers[ast_operator_type::AST_OP_ADD] = &IRGenerator::ir_add;
    ast2ir_handlers[ast_operator_type::AST_OP_MUL] = &IRGenerator::ir_mul;
    ast2ir_handlers[ast_operator_type::AST_OP_DIV] = &IRGenerator::ir_div;
    ast2ir_handlers[ast_operator_type::AST_OP_MOD] = &IRGenerator::ir_mod;
    ast2ir_handlers[ast_operator_type::AST_OP_NEG] = &IRGenerator::ir_neg;

    /* 语句 */
    ast2ir_handlers[ast_operator_type::AST_OP_EXPR] = &IRGenerator::ir_expr_noshow;
    ast2ir_handlers[ast_operator_type::AST_OP_EXPR_SHOW] = &IRGenerator::ir_expr_show;
    ast2ir_handlers[ast_operator_type::AST_OP_ASSIGN] = &IRGenerator::ir_assign;
    ast2ir_handlers[ast_operator_type::AST_OP_RETURN_STATEMENT] = &IRGenerator::ir_return;

    /* 函数调用 */
    ast2ir_handlers[ast_operator_type::AST_OP_FUNC_CALL] = &IRGenerator::ir_function_call;

    /* 函数定义 */
    ast2ir_handlers[ast_operator_type::AST_OP_FUNC_DEF] = &IRGenerator::ir_function_define;
    ast2ir_handlers[ast_operator_type::AST_OP_FUNC_FORMAL_PARAMS] = &IRGenerator::ir_function_formal_params;

    /* 语句块 */
    ast2ir_handlers[ast_operator_type::AST_OP_BLOCK] = &IRGenerator::ir_block;

    /* 编译单元 */
    ast2ir_handlers[ast_operator_type::AST_OP_COMPILE_UNIT] = &IRGenerator::ir_compile_unit;

	/* 变量声明 */
	ast2ir_handlers[ast_operator_type::AST_OP_VAR_DECL] = &IRGenerator::ir_var_decl;
	ast2ir_handlers[ast_operator_type::AST_OP_FUNC_DECL] = &IRGenerator::ir_function_decl;
	ast2ir_handlers[ast_operator_type::AST_OP_VAR_LIST] = &IRGenerator::ir_var_list;
	ast2ir_handlers[ast_operator_type::AST_OP_ARRAY_DEF] = &IRGenerator::ir_array_def;
	ast2ir_handlers[ast_operator_type::AST_OP_ARRAY_CALL] = &IRGenerator::ir_array_call;

	/* 逻辑语句 */
	ast2ir_handlers[ast_operator_type::AST_LOG_AND] = &IRGenerator::ir_log_and;
	ast2ir_handlers[ast_operator_type::AST_LOG_OR] = &IRGenerator::ir_log_or;
	ast2ir_handlers[ast_operator_type::AST_LOG_NOT] = &IRGenerator::ir_log_not;

	/* 关系语句 */
	ast2ir_handlers[ast_operator_type::AST_REL_GT] = &IRGenerator::ir_rel;
	ast2ir_handlers[ast_operator_type::AST_REL_LT] = &IRGenerator::ir_rel;
	ast2ir_handlers[ast_operator_type::AST_REL_GE] = &IRGenerator::ir_rel;
	ast2ir_handlers[ast_operator_type::AST_REL_LE] = &IRGenerator::ir_rel;
	ast2ir_handlers[ast_operator_type::AST_REL_EQ] = &IRGenerator::ir_rel;
	ast2ir_handlers[ast_operator_type::AST_REL_NEQ] = &IRGenerator::ir_rel;
	
	/* if语句 */
	ast2ir_handlers[ast_operator_type::AST_OP_IF] = &IRGenerator::ir_if;

	/* while语句 */
	ast2ir_handlers[ast_operator_type::AST_OP_WHILE] = &IRGenerator::ir_while;

	/* for语句 */
	ast2ir_handlers[ast_operator_type::AST_OP_FOR] = &IRGenerator::ir_for;

	/* break和continue语句 */
	ast2ir_handlers[ast_operator_type::AST_OP_BREAK] = &IRGenerator::ir_break;
	ast2ir_handlers[ast_operator_type::AST_OP_CONTINUE] = &IRGenerator::ir_continue;

	/* 自增自减语句 */
	ast2ir_handlers[ast_operator_type::AST_OP_INCR_PREV] = &IRGenerator::ir_incr_prev;
	ast2ir_handlers[ast_operator_type::AST_OP_INCR_POST] = &IRGenerator::ir_incr_post;
	ast2ir_handlers[ast_operator_type::AST_OP_DECR_PREV] = &IRGenerator::ir_decr_prev;
	ast2ir_handlers[ast_operator_type::AST_OP_DECR_POST] = &IRGenerator::ir_decr_post;
}

/// @brief 编译单元AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_compile_unit(ast_node * node)
{
	symtab->currentFunc = nullptr;
    // 新建main函数并默认设置当前函数为main函数
    symtab->globalFunc = symtab->newFunction("@global", BasicType::TYPE_INT);
    symtab->currentFunc = symtab->globalFunc;


    // 获取函数的IR代码列表，用于后面追加指令用，注意这里用的是引用传值
    InterCode & irCode = symtab->currentFunc->getInterCode();

	for (auto son: node->sons) {

        // 遍历编译单元，要么是函数定义，要么是语句
        ast_node * son_node = ir_visit_ast_node(son);
        if (!son_node) {
            return false;
        }

        node->blockInsts.addInst(son_node->blockInsts);
    }

	// 添加全局声明
	irCode.addInst(symtab->globalFunc->declInsts);

    // 除了函数定义的指令外都加入到main函数的指令当中
    irCode.addInst(node->blockInsts);


    return true;
}

/// @brief 函数定义AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_function_define(ast_node * node)
{
    // 创建一个函数，用于当前函数处理
    if (symtab->currentFunc != symtab->globalFunc) {
        // 函数中嵌套定义函数，这是不允许的，错误退出
        printf("line no: %u ，函数中嵌套定义函数\n", node->line_no);
        return false;
    }

    // 创建一个新的函数定义，函数的返回类型设置为VOID，待定，必须等return时才能确定，目前可以是VOID或者INT类型
    symtab->currentFunc = new Function("@" + node->name, BasicType::TYPE_VOID);
	if (symtab->currentFunc->getName() == "@main") symtab->mainFunc = symtab->currentFunc;
    bool result = symtab->insertFunction(symtab->currentFunc);
    if (!result) {
        // 清理资源
        delete symtab->currentFunc;

        // 恢复当前函数指向main函数
        symtab->currentFunc = symtab->mainFunc;

        // 函数已经定义过了，不能重复定义，语义错误：出错返回。
        printf("line no: %u ，函数中重定义\n", node->line_no);

        return false;
    }

	symtab->currentFunc->setSymtab(symtab);

    // 获取函数的IR代码列表，用于后面追加指令用，注意这里用的是引用传值
    InterCode & irCode = symtab->currentFunc->getInterCode();

    // 增加一个函数入口Label指令，便于后续基本块划分
    IRInst * LabelInst = new LabelIRInst();

	// 创建出口指令
    IRInst * exitLabelInst = new LabelIRInst();

    // 函数出口指令保存到函数信息中，因为在语义分析函数体时return语句需要跳转到函数尾部，需要这个label指令
    symtab->currentFunc->setExitLabel(exitLabelInst);

    // 新建一个Value，用于保存函数的返回值，如果没有返回值可不用申请，
    // 目前未知，先创建一个，不用后续可释放
    Value * retValue = symtab->currentFunc->newVarValue(BasicType::TYPE_INT);

    // 保存函数返回值变量到函数信息中，在return语句翻译时需要设置值到这个变量中
    symtab->currentFunc->setReturnValue(retValue);

	// 为了考虑递归的情况，得先将返回值类型判断出来
	ValueType & returnType = symtab->currentFunc->getReturnType();
	if (node->sons[0]->name == "int") {
		returnType.type = BasicType::TYPE_INT;
	}


    // 遍历函数体内的每个语句
    for (auto son: node->sons) {

        // 遍历函数定义，孩子要么是形式参数，要么是block
        ast_node * son_node = ir_visit_ast_node(son);
        if (!son_node) {

            // 对函数体内的语句进行语义分析时出现错误
            return false;
        }

        // IR指令追加到当前的节点中
        node->blockInsts.addInst(son_node->blockInsts);
    }

	irCode.addInst(symtab->currentFunc->declInsts);

	irCode.addInst(LabelInst);
	// 创建并加入Entry入口指令
    irCode.addInst(new EntryIRInst());
	irCode.addInst(symtab->currentFunc->initInsts);



    // 此时，所有指令都加入到当前函数中，也就是node->blockInsts
    // node节点的指令移动到函数的IR指令列表中
    irCode.addInst(node->blockInsts);


    // 添加函数出口Label指令，主要用于return语句跳转到这里进行函数的退出
    irCode.addInst(exitLabelInst);

    // 检查函数是否有返回值类型，则需要设置返回值，否则不设置
    if (symtab->currentFunc->getReturnType().type != BasicType::TYPE_VOID) {
        // 函数出口指令
        irCode.addInst(new ExitIRInst(retValue));
    } else {
        // 清理资源恢复原状
        symtab->currentFunc->deleteVarValue(retValue);
        symtab->currentFunc->setReturnValue(nullptr);
        delete retValue;

        // 函数出口指令
        irCode.addInst(new ExitIRInst());
    }

    // 恢复成指向全局
    symtab->currentFunc = symtab->globalFunc;

    return true;
}

/// @brief 函数声明AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_function_decl(ast_node * node)
{
	// 创建一个函数，用于当前函数处理
    if (symtab->currentFunc != symtab->globalFunc) {
        // 函数中嵌套声明函数，这是不允许的，错误退出
        printf("line no: %u ，函数中嵌套声明函数\n", node->line_no);
        return false;
    }

    // 创建一个新的函数定义，函数的返回类型设置为VOID，待定，必须等return时才能确定，目前可以是VOID或者INT类型
	std::string funcName = "@" + node->name;
	// 检测是否是内置函数
	auto pfunc = symtab->findFunction(funcName);
	if (pfunc && pfunc->isBuiltin()) return true;
    symtab->currentFunc = new Function(funcName, BasicType::TYPE_VOID, true);
	if (symtab->currentFunc->getName() == "@main") symtab->mainFunc = symtab->currentFunc;
    bool result = symtab->insertFunction(symtab->currentFunc);
    if (!result) {
        // 清理资源
        delete symtab->currentFunc;
        symtab->currentFunc = symtab->globalFunc;

        // 函数已经定义过了，不能重复定义，语义错误：出错返回。
        printf("line no: %u ，函数中重定义\n", node->line_no);

        return false;
    }

	// 新建一个Value，用于保存函数的返回值，如果没有返回值可不用申请，
    // 目前未知，先创建一个，不用后续可释放
    Value * retValue = symtab->currentFunc->newVarValue(BasicType::TYPE_INT);

    // 保存函数返回值变量到函数信息中，在return语句翻译时需要设置值到这个变量中
    symtab->currentFunc->setReturnValue(retValue);

#define FUNC_PARAMS_POS 1
	if (!ir_function_formal_params(node->sons[FUNC_PARAMS_POS])) {
		printf("函数%s中声明参数有问题\n", node->name.c_str());
		return false;
	}

	// 判断是否有返回值
	ValueType & returnType = symtab->currentFunc->getReturnType();
#define FUNC_RETURN_TYPE_POS 0
    if (node->type.type == BasicType::TYPE_INT) {
        // 设置类型
        returnType.type = BasicType::TYPE_INT;
    }
    // 恢复成指向全局
    symtab->currentFunc = symtab->globalFunc;

    return true;
}

/// @brief 形式参数AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_function_formal_params(ast_node * node)
{
    // 获取当前要保存函数的形式参数清单
    auto & params = symtab->currentFunc->getParams();

    // 遍历形式参数列表，孩子是叶子节点
    for (auto son: node->sons) {
		if (son->type.type == BasicType::TYPE_INT_POINT) {
			// 创建变量，默认整型
			Value * var = new TempValue(BasicType::TYPE_INT_POINT);
			symtab->currentFunc->setVar(TMP_FLAG + son->name, var);
			params.emplace_back(var->getName(), BasicType::TYPE_INT_POINT, var);
		} else {
			// 创建变量，默认整型
			Value * var = new TempValue(BasicType::TYPE_INT);
			symtab->currentFunc->setVar(TMP_FLAG + son->name, var);

			// 默认是整数类型
			// TODO：支持数组类型参数
			params.emplace_back(var->getName(), BasicType::TYPE_INT, var);
		}
    }

    return true;
}

/// @brief 函数调用AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_function_call(ast_node * node)
{
    std::vector<Value *> realParams;
    // 根据函数名查找函数，看是否存在。若不存在则出错
    // 这里约定函数必须先定义后使用
	std::string funtionName = '@' + node->name;
    auto pFunction = symtab->findFunction(funtionName);


    if (nullptr == pFunction) {
        printf("无名为%s的函数\n", node->name.c_str());
        return false;
    }

	auto & params = pFunction->getParams();

    // 设置存在函数调用
    symtab->currentFunc->setExistFuncCall(true);

    // 如果没有孩子，也认为是没有参数
    if (!node->sons.empty()) {

        // 只有一个节点，实际参数列表
        auto paramsNode = node->sons[0];

        int argsCount = (int) paramsNode->sons.size();

        // 设置最大函数调用参数个数
        if (argsCount > symtab->currentFunc->getMaxFuncCallArgCnt()) {
            symtab->currentFunc->setMaxFuncCallArgCnt(argsCount);
        }

        // 遍历参数列表，孩子是表达式
        // 这里自左往右计算表达式
		int i = 0;
        for (auto son: paramsNode->sons) {
            // 遍历Block的每个语句，进行显示或者运算
            ast_node * temp = ir_visit_ast_node(son);
            if (!temp) {
                return false;
            }
			node->blockInsts.addInst(temp->blockInsts);
			if (temp->val->type.type != params[i].type.type) {
				Value * param = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
				node->blockInsts.addInst(new AssignIRInst(param, temp->val));
				temp->val = param;
			}
            realParams.push_back(temp->val);
			i++;
        }
    }

    // 创建临时变量，用于保存函数调用的结果
    Value * resultVal = nullptr;

    // 返回调用有返回值，则需要分配临时变量
    if (pFunction->getReturnType().type != BasicType::TYPE_VOID) {
        resultVal = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    } 

    // 创建函数调用指令
    node->blockInsts.addInst(new FuncCallIRInst(node->name, realParams, resultVal));

    // 设置存在函数调用，后面要根据是否函数调用进行调整栈分配策略
    symtab->currentFunc->setExistFuncCall(true);

    // 函数调用结果保存到node中，用于外部使用
    node->val = resultVal;

    return true;
}

/// @brief 语句块AST节点变量清空
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_block_var_clear()
{
	if (symtab->blockDepth >= 2) {
		auto& vars = symtab->currentFunc->getVarValues();
		for (auto& var : vars) {
			std::string blockDepth;
			for (int i = 0; i < var->name.size(); i++) {
				if (!isDigital(var->name[i])) {
					break;
				}
				blockDepth += var->name[i];
			}
			if (blockDepth == std::to_string(symtab->blockDepth)) {
				symtab->currentFunc->deleteVarValue(var);
			}
		}
	}
	return true;
}

/// @brief 语句块（含函数体）AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_block(ast_node * node)
{
    std::vector<ast_node *>::iterator pIter;
	symtab->blockDepth++;
    for (pIter = node->sons.begin(); pIter != node->sons.end(); ++pIter) {

        // 遍历Block的每个语句，进行显示或者运算
        ast_node * temp = ir_visit_ast_node(*pIter);
        if (!temp) {
            return false;
        }

        node->blockInsts.addInst(temp->blockInsts);
    }
	// 每出一个block，将其中的值清空
	ir_block_var_clear();
	symtab->blockDepth--;
    return true;
}

/// @brief 表达式语句ST节点翻译成线性中间IR的共同函数
/// @param node AST节点
/// @param show 是否显示值，true：显示，false：不显示
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_show_internal(ast_node * node, bool show)
{
    // TODO real number print

    ast_node * src1_node = node->sons[0];

    ast_node * result = ir_visit_ast_node(src1_node);
    if (!result) {
        // 解析错误
        return false;
    }

    node->blockInsts.addInst(result->blockInsts);

    node->val = nullptr;

    return true;
}

/// @brief 不显示表达式AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_expr_noshow(ast_node * node)
{
    return ir_show_internal(node, false);
}

/// @brief 显示表达式AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_expr_show(ast_node * node)
{
    return ir_show_internal(node, true);
}

/// @brief 整数加法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_add(ast_node * node)
{
    ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

    // 加法节点，左结合，先计算左节点，后计算右节点

    // 加法的左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }


    // 加法的右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    Value * resultValue;

    if (left->val->type.type == BasicType::TYPE_FLOAT || right->val->type.type == BasicType::TYPE_FLOAT) {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_FLOAT);
    } else {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    }

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);
	Value* lval;
	if (left->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, left->val));
		lval = tmp;
	} else {
		lval = left->val;
	}
    node->blockInsts.addInst(right->blockInsts);
	Value* rval;
	if (right->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, right->val));
		rval = tmp;
	} else {
		rval = right->val;
	}
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_ADD_I, resultValue, lval, rval));
    node->val = resultValue;

    return true;
}

/// @brief 整数减法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_sub(ast_node * node)
{
    ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

    // 加法节点，左结合，先计算左节点，后计算右节点

    // 加法的左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 加法的右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    // 这里只处理整型的数据，如需支持实数，则需要针对类型进行处理
    Value * resultValue;

    // 这里只处理整型的数据，如需支持实数，则需要针对类型进行处理
    if (left->val->type.type == BasicType::TYPE_FLOAT || right->val->type.type == BasicType::TYPE_FLOAT) {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_FLOAT);
    } else {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    }

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);
	Value* lval;
	if (left->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, left->val));
		lval = tmp;
	} else {
		lval = left->val;
	}

    node->blockInsts.addInst(right->blockInsts);
	Value* rval;
	if (right->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, right->val));
		rval = tmp;
	} else {
		rval = right->val;
	}
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_SUB_I, resultValue, lval, rval));
    node->val = resultValue;

    return true;
}

/// @brief 整数乘法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_mul(ast_node * node)
{
    ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

    // 加法节点，左结合，先计算左节点，后计算右节点

    // 加法的左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 加法的右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    Value * resultValue;

    if (left->val->type.type == BasicType::TYPE_FLOAT || right->val->type.type == BasicType::TYPE_FLOAT) {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_FLOAT);
    } else {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    }

    // 创建临时变量保存IR的值，以及线性IR指令
    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);
	Value* lval;
	if (left->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, left->val));
		lval = tmp;
	} else {
		lval = left->val;
	}
	
    node->blockInsts.addInst(right->blockInsts);
	Value* rval;
	if (right->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, right->val));
		rval = tmp;
	} else {
		rval = right->val;
	}
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_MUL_I, resultValue, lval, rval));
    node->val = resultValue;

    return true;
}

/// @brief 整数除法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_div(ast_node * node)
{
    ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

    // 加法节点，左结合，先计算左节点，后计算右节点

    // 加法的左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 加法的右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    Value * resultValue;

    if (left->val->type.type == BasicType::TYPE_FLOAT || right->val->type.type == BasicType::TYPE_FLOAT) {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_FLOAT);
    } else {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    }

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);
	Value* lval;
	if (left->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, left->val));
		lval = tmp;
	} else {
		lval = left->val;
	}
	
    node->blockInsts.addInst(right->blockInsts);
	Value* rval;
	if (right->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, right->val));
		rval = tmp;
	} else {
		rval = right->val;
	}
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_DIV_I, resultValue, lval, rval));
    node->val = resultValue;

    return true;
}

/// @brief 整数取模AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_mod(ast_node * node)
{
    ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

    // 加法的左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 加法的右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    Value * resultValue;

    // 这里只处理整型的数据，如需支持实数，则需要针对类型进行处理
    if (left->val->type.type == BasicType::TYPE_FLOAT || right->val->type.type == BasicType::TYPE_FLOAT) {
        printf("取余错误\n");
        return false;
    } else {
        resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    }

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);
    node->blockInsts.addInst(right->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_MOD_I, resultValue, left->val, right->val));
    node->val = resultValue;

    return true;
}

/// @brief 赋值AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_assign(ast_node * node)
{
    ast_node * son1_node = node->sons[0];
    ast_node * son2_node = node->sons[1];

    // 赋值节点，自右往左运算
	// 当在全局中赋值变量就只有初始化全局变量这一种情况，声明要特殊给值
	if (symtab->currentFunc == symtab->globalFunc)
	{
		std::string name = son1_node->name;
		Value* Val = new VarValue(name, '@' + name, BasicType::TYPE_INT);
		auto* decl = new DeclIRInst('@' + name, BasicType::TYPE_INT, true);
		ast_node * right = ir_visit_ast_node(son2_node);
		if (!right) {
			// 某个变量没有定值
			return false;
		}
		
		decl->setAssignment(" = " + std::to_string(right->val->intVal));

        symtab->insertValue(Val);
		symtab->globalFunc->declInsts.addInst(decl);

        return true;
	}

    // 赋值运算符的左侧操作数
    ast_node * left = ir_visit_ast_node(son1_node);
    if (!left) {
        // 某个变量没有定值
        // 这里缺省设置变量不存在则创建，因此这里不会错误
        return false;
    }

    // 赋值运算符的右侧操作数
    ast_node * right = ir_visit_ast_node(son2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    // 创建临时变量保存IR的值，以及线性IR指令
	// 当左值是函数参数，并且刚进行完初始化，现在必须先加左块的语句，后加右块的语句
	// TODO：这里只是妥协性的解决方式，如果参数是数组可能出现一些问题，等后面有问题了再说
	if (left->val->isParamAndAssign) {
		node->blockInsts.addInst(left->blockInsts);
		node->blockInsts.addInst(right->blockInsts);
		left->val->isParamAndAssign = false;
	} else {
		node->blockInsts.addInst(right->blockInsts);
    	node->blockInsts.addInst(left->blockInsts);
	}
	

	Value* rval;
	if (right->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, right->val));
		rval = tmp;
	} else {
		rval = right->val;
	}

	node->blockInsts.addInst(new AssignIRInst(left->val, rval));

	// 这里假定赋值的类型是一致的
    // left->val->type = right->val->type;
    node->val = left->val;

	// TODO：目前还不支持指针赋值，有指针直接解引用
    return true;
}

/// @brief 取负AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_neg(ast_node * node)
{
    ast_node * src_node = node->sons[0];

    // 取负节点，只有一个孩子节点，即被取负的表达式

    // 获取被取负的表达式的值
    ast_node * operand = ir_visit_ast_node(src_node);
    if (!operand) {
        // 某个变量没有定值
        return false;
    }

    Value * resultValue;

	// 全局变量赋负值可以直接赋，但是局部变量还是需要将正数取负再赋值 
	if (operand->val->isConst() && src_node->node_type == ast_operator_type::AST_OP_LEAF_LITERAL_INT && symtab->currentFunc == symtab->globalFunc) {
		resultValue = symtab->newConstValue(-1 * operand->val->intVal);
	} else {
		// 创建临时变量保存负数的值，以及线性IR指令
		if (operand->val->type.type == BasicType::TYPE_FLOAT) {
			resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_FLOAT);
		} else {
			resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		}
		node->blockInsts.addInst(operand->blockInsts);
		node->blockInsts.addInst(new NegIRInst(resultValue, operand->val));
	}

    // 结果保存到当前节点中
    node->val = resultValue;

    return true;
}

/// @brief 自增自减公共部分
/// @param node AST节点
/// @return 表达式值
Value * IRGenerator::ir_self_modify_common(ast_node * node)
{
	ast_node * expr_node = node->sons[0];

    ast_node * Expr = ir_visit_ast_node(expr_node);
    if (!Expr) {
        // 某个变量没有定值
        return nullptr;
    }

    node->blockInsts.addInst(Expr->blockInsts);

	Value * exprValue;
	if (Expr->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, Expr->val));
		exprValue = tmp;
	} else {
		exprValue = Expr->val;
	}

	return exprValue;
}

/// @brief 前置自增AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_incr_prev(ast_node * node)
{
	Value * exprValue = ir_self_modify_common(node);
	if (!exprValue) {
		return false;
	}
	Value * resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);

	node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_ADD_I, resultValue, exprValue, symtab->newConstValue((int32_t) 1)));
	node->blockInsts.addInst(new AssignIRInst(exprValue, resultValue));

	node->val = resultValue;

	return true;
}

/// @brief 后置自增AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_incr_post(ast_node * node)
{
	Value * exprValue = ir_self_modify_common(node);
	if (!exprValue) {
		return false;
	}
	Value * prevExprValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
	node->blockInsts.addInst(new AssignIRInst(prevExprValue, exprValue));
	Value * curExprValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
	node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_ADD_I, curExprValue, exprValue, symtab->newConstValue((int32_t) 1)));
	node->blockInsts.addInst(new AssignIRInst(exprValue, curExprValue));

	Value * resultValue = prevExprValue;
	node->val = resultValue;

	return true;
}

/// @brief 前置自减AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_decr_prev(ast_node * node)
{
	Value * exprValue = ir_self_modify_common(node);
	if (!exprValue) {
		return false;
	}
	Value * resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);

	node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_SUB_I, resultValue, exprValue, symtab->newConstValue((int32_t) 1)));
	node->blockInsts.addInst(new AssignIRInst(exprValue, resultValue));

	node->val = resultValue;

	return true;
}

/// @brief 后置自减AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_decr_post(ast_node * node)
{
	Value * exprValue = ir_self_modify_common(node);
	if (!exprValue) {
		return false;
	}
	Value * prevExprValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
	node->blockInsts.addInst(new AssignIRInst(prevExprValue, exprValue));
	Value * curExprValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
	node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_SUB_I, curExprValue, exprValue, symtab->newConstValue((int32_t) 1)));
	node->blockInsts.addInst(new AssignIRInst(exprValue, curExprValue));

	Value * resultValue = prevExprValue;
	node->val = resultValue;

	return true;
}

/// @brief return节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_return(ast_node * node)
{
    ast_node * right = nullptr;

    // return语句可能没有没有表达式，也可能有，因此这里必须进行区分判断
    if (!node->sons.empty()) {

        ast_node * son_node = node->sons[0];

        // 返回的表达式的指令保存在right节点中
        right = ir_visit_ast_node(son_node);
        if (!right) {

            // 某个变量没有定值
            return false;
        }
    }

    if (!right) {
		// 跳转到函数的尾部出口指令上
    	node->blockInsts.addInst(new GotoIRInst(symtab->currentFunc->getExitLabel()));
		return true;
	}

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(right->blockInsts);

    // 返回值赋值到函数返回值变量上，然后跳转到函数的尾部
    node->blockInsts.addInst(new AssignIRInst(symtab->currentFunc->getReturnValue(), right->val));

    // 跳转到函数的尾部出口指令上
    node->blockInsts.addInst(new GotoIRInst(symtab->currentFunc->getExitLabel()));

    node->val = right->val;

    return true;
}

/// @brief 标识符叶子节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_leaf_node_var_id(ast_node * node)
{
    Value * val = nullptr;

    // 新建一个ID型Value
	// TODO：判断是否为关键字
	if (node->name == "int" || node->name == "void") return true;

    // 变量，则需要在符号表中查找对应的值
    // 若变量之前没有有定值，则采用默认的值为0

	// 当此时在全局时
	if (symtab->currentFunc == symtab->globalFunc) {
		val = symtab->findValue(node->name, false);

		if (!val) {
			// 变量不存在，则创建一个变量
			val = symtab->newVarValue(node->name);
			// printf("%s\n", val->getRegName().c_str());
		} 
	} else if ((node->parent && node->parent->parent && node->parent->parent->node_type == ast_operator_type::AST_OP_VAR_LIST && node->parent->sons[0] == node) \
			|| (node->parent && node->parent->node_type == ast_operator_type::AST_OP_VAR_LIST)) {
		// 当是创建局部变量左值时，直接创建，不用查找
		// 当创建block层数大于等于2的变量时，要变量名加前缀，防止变量名重复
		if (symtab->blockDepth >= 2) {
			val = symtab->currentFunc->newVarValueDirectly(std::to_string(symtab->blockDepth) + node->name);
		} else {
			// 要直接创建时，不能使用newVarValue，里面有查找的过程，会查找全局变量
			val = symtab->currentFunc->newVarValueDirectly(node->name);
		}
	} else {
		// 查找右值
		int blockDepth = symtab->blockDepth;
		while (blockDepth >= 2) {
			val = symtab->currentFunc->findValue(std::to_string(blockDepth) + node->name, false);
			if (val) break;
			blockDepth--;
		}
		if (!val) {
			val = symtab->currentFunc->findValueOnlyInThisFuncion(node->name, false);

			if (!val) {
				// 找函数参数的临时变量
				Value* param = symtab->currentFunc->findValue(TMP_FLAG + node->name, false);
				if (param) {
					// 此变量是函数参数（实参），需要用局部变量重新赋值
					// 要直接创建时，不能使用newVarValue，里面有查找的过程，会查找全局变量
					if (param->type.type == BasicType::TYPE_INT_POINT) {
						val = symtab->currentFunc->newVarValueDirectly(node->name, BasicType::TYPE_INT_POINT);
					} else {
						val = symtab->currentFunc->newVarValueDirectly(node->name);
					}
					val->isParamAndAssign = true;
					symtab->currentFunc->initInsts.addInst(new AssignIRInst(val, param, true));
				}
				// 找全局变量
				if (!val) val = symtab->findValue(node->name, false);

			}
		}
	}

    node->val = val;

    return true;
}

/// @brief 有符号整数字面量叶子节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_leaf_node_int(ast_node * node)
{
    Value * val;

    // 新建一个整数常量Value
    val = symtab->newConstValue((int32_t) node->integer_val);

    node->val = val;

    return true;
}

/// @brief float数字面量叶子节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_leaf_node_float(ast_node * node)
{
    Value * val = nullptr;

    // 新建一个实数型常量Value
    val = symtab->newConstValue(node->float_val);

    node->val = val;

    return true;
}

/// @brief 变量声明节点类型的节点处理
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_var_decl(ast_node * node)
{
	// TODO 以后支持浮点数
	ast_node * type_node = node->sons[0];
	ast_node * var_list_node = node->sons[1];

	// 目前先定为int
	if (type_node->type.type == BasicType::TYPE_VOID) {
		var_list_node->type.type = BasicType::TYPE_VOID;
	}
	var_list_node->type.type = BasicType::TYPE_INT;

	ast_node * right = ir_visit_ast_node(var_list_node);
	if (!right) {
		return false;
	}

	// 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(right->blockInsts);
	
	return true;
}

/// @brief 变量初始化列表节点类型的节点处理
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_var_list(ast_node * node)
{
	for (auto son: node->sons) {

        // 遍历编译单元，要么是函数定义，要么是语句
        ast_node * son_node = ir_visit_ast_node(son);
        if (!son_node) {
            return false;
        }

        node->blockInsts.addInst(son_node->blockInsts);
    }
	return true;
}

/// @brief 数组定义节点类型的节点处理
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_array_def(ast_node * node)
{
	// TODO 以后支持浮点数
	// 数组名字节点
	ast_node * name_node = node->sons[0];
	// 查看维度
	std::vector<std::string> dims;
	int dimVal = 0;
	for (int i = 1; i < node->sons.size(); ++i) {
		// printf("%d\n", node->sons[i]->integer_val);
        dims.push_back(std::to_string(node->sons[i]->integer_val));
		dimVal++;
    }

	Value * val;

	// 当此时在全局时
	if (symtab->currentFunc == symtab->globalFunc) {
		val = symtab->findValue(name_node->name, false);

		if (!val) {
			// 变量不存在，则创建一个变量
			val = symtab->newVarArrValue(name_node->name, dims);
			val->dimVal = dimVal;
			val->dimensions = dims;
			// printf("%s\n", tmp.c_str());
		}
	} else {
		val = symtab->currentFunc->findValue(name_node->name, false);
			if (!val) {
				val = symtab->findValue(name_node->name, false);
				if (!val) {
					// 变量不存在，则创建一个变量
					val = symtab->currentFunc->newVarArrValue(name_node->name, dims);
					val->dimVal = dimVal;
					val->dimensions = dims;
			} 
		}
	}

    node->val = val;
	return true;
}

/// @brief 使用数组节点类型的节点处理
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_array_call(ast_node * node)
{
	// 数组名字节点
	ast_node * name_node = node->sons[0];
	Value * val;
	// 当此时在全局时
	if (symtab->currentFunc == symtab->globalFunc) {
		val = symtab->findValue(name_node->name, false);

		if (!val) {
			printf("%s: 此数组未声明\n", name_node->name.c_str());
			return false;
		}
	} else {
		val = symtab->currentFunc->findValueOnlyInThisFuncion(name_node->name, false);
		if (!val) {
			// 找函数参数的临时变量
			Value* param = symtab->currentFunc->findValue(TMP_FLAG + name_node->name, false);
			if (param) {
				// TODO：目前只能传递一维数组
				std::vector<std::string> dims;
				dims.push_back("0");
				val = symtab->currentFunc->newVarArrValueDirectly(name_node->name, dims);
				val->isParamAndAssign = true;
				val->dimVal = 1;
				val->dimensions = dims;
				symtab->currentFunc->initInsts.addInst(new AssignIRInst(val, param, true));
			}
			if (!val) val = symtab->findValue(name_node->name, false);
			if (!val) {
				printf("%s: 此数组未声明\n", name_node->name.c_str());
				return false;
			} 
		}
	}

	// 生成计算数组维度的ir
	if (node->sons[1] == nullptr) {
		printf("%s: 此数组的定义出错\n", name_node->name.c_str());
		return false;
	}
	ast_node * son_node = node->sons[1];
	if (!son_node) {
		return false;
	}

	auto& dims = val->dimensions;
	Value * cur;

	if (son_node->sons.size() > 1) { // 多维
		for (int i = 0; i < son_node->sons.size(); ++i) {
			auto* son = son_node->sons[i];
			auto* retVal = ir_visit_ast_node(son);
			if (retVal == nullptr) {
				return false;
			}
			son_node->blockInsts.addInst(retVal->blockInsts);

			Value * dimVal = retVal->val;
			Value * c1 = nullptr;
			Value * t1 = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
			Value * t2 = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);

			// 数组套数组这样的调用必须先解引用
			if (dimVal->type.type == BasicType::TYPE_INT_POINT) {
				Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
				son_node->blockInsts.addInst(new AssignIRInst(tmp, dimVal));
				dimVal = tmp;
			}

			if (i > 0) {
				son_node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_ADD_I, t1, cur, dimVal));
				cur = t1;
			}

			if (i != son_node->sons.size() - 1) {
				c1 = symtab->newConstValue((int32_t) std::stoi(dims[i + 1]));
				if (i > 0) {
					son_node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_MUL_I, t2, t1, c1));
				} else {
					son_node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_MUL_I, t2, dimVal, c1));
				}
				cur = t2;
			}
		}
	} else { // 一维
		auto* son = son_node->sons[0];
		auto* retVal = ir_visit_ast_node(son);
		if (retVal == nullptr) {
			return false;
		}
		son_node->blockInsts.addInst(retVal->blockInsts);
		// 数组套数组这样的调用必须先解引用
		if (retVal->val->type.type == BasicType::TYPE_INT_POINT) {
			Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
			son_node->blockInsts.addInst(new AssignIRInst(tmp, retVal->val));
			retVal->val = tmp;
		}
		cur = retVal->val;
	}

	Value * len = symtab->newConstValue((int32_t) 4);
	Value * t1 = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
	son_node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_MUL_I, t1, cur, len));

	Value * point = symtab->currentFunc->newTempValue(BasicType::TYPE_INT_POINT);
	son_node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_ADD_I, point, val, t1));

	node->val = point;

	node->blockInsts.addInst(son_node->blockInsts);

	return true;
}

static IRInstOperator getRelOperator(ast_operator_type op)
{
	switch (op) {
		case ast_operator_type::AST_REL_NEQ:
			return IRInstOperator::IRINST_REL_NEQ;
			break;
		case ast_operator_type::AST_REL_EQ:
			return IRInstOperator::IRINST_REL_EQ;
			break;
		case ast_operator_type::AST_REL_LT:
			return IRInstOperator::IRINST_REL_LT;
			break;
		case ast_operator_type::AST_REL_GT:
			return IRInstOperator::IRINST_REL_GT;
			break;
		case ast_operator_type::AST_REL_LE:
			return IRInstOperator::IRINST_REL_LE;
			break;
		case ast_operator_type::AST_REL_GE:
			return IRInstOperator::IRINST_REL_GE;
			break;
		default:
			break;
	}
	return IRInstOperator::IRINST_OP_MAX;
}

static bool isRelOrLogOp(ast_operator_type op)
{
	if (getRelOperator(op) != IRInstOperator::IRINST_OP_MAX) {
		return true;
	}
	if (op == ast_operator_type::AST_LOG_AND || op == ast_operator_type::AST_LOG_OR || op == ast_operator_type::AST_LOG_NOT) {
		return true;
	}

	return false;
}

static bool isLogOp(ast_operator_type op)
{
	if (op == ast_operator_type::AST_LOG_AND || op == ast_operator_type::AST_LOG_OR || op == ast_operator_type::AST_LOG_NOT) {
		return true;
	}
	return false;
}

/// @brief 将条件中的非关系表达式转换为条件表达
/// @param cond_node 条件AST节点
/// @param parent_node 关系AST节点
void IRGenerator::condPoint2Int(ast_node * cond_node, ast_node * parent_node)
{
	if (!isRelOrLogOp(cond_node->node_type)) {
		// 当是数组表达式时，要将其转换为i32形式
		Value* cval;
		if (cond_node->val->type.type == BasicType::TYPE_INT_POINT) {
			Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
			parent_node->blockInsts.addInst(new AssignIRInst(tmp, cond_node->val));
			cval = tmp;
		} else {
			cval = cond_node->val;
		}
		Value * t1 = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
        parent_node->blockInsts.addInst(new RelIRInst(IRInstOperator::IRINST_REL_NEQ, t1, cval, symtab->newConstValue((int32_t) 0)));
		parent_node->blockInsts.addInst(new GotoIRInst(t1, cond_node->trueLabel, cond_node->falseLabel));
	}
}

/// @brief if语句块AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_if(ast_node * node)
{
	ast_node * cond_node = node->sons[0];
    ast_node * true_node = node->sons[1];
    ast_node * false_node = nullptr;
	if (node->sons.size() == 3) {
        false_node = node->sons[2];
    }

	// 先创建三个Label
	LabelIRInst * trueLabel = new LabelIRInst(), * falseLabel = new LabelIRInst();
	LabelIRInst * exitLabel = new LabelIRInst();

	cond_node->trueLabel = trueLabel, cond_node->falseLabel = falseLabel;

    // 条件判断
    ast_node * Cond = ir_visit_ast_node(cond_node);
    if (!Cond) {
        return false;
    }
	node->blockInsts.addInst(Cond->blockInsts);
	// 当孩子节点不是逻辑表达式时，还需要加自己加bool转换和有条件跳转语句
	condPoint2Int(Cond, node);
	node->blockInsts.addInst(trueLabel);

    // 真语句
    ast_node * True = ir_visit_ast_node(true_node);
    if (!True) {
        return false;
    }
	node->blockInsts.addInst(True->blockInsts);
	node->blockInsts.addInst(new GotoIRInst(exitLabel));
	node->blockInsts.addInst(falseLabel);

	// 假语句
	ast_node * False = nullptr;
	if (false_node) {
		False = ir_visit_ast_node(false_node);
		if (!False) {
        	return false;
    	}
		node->blockInsts.addInst(False->blockInsts);
	}
	node->blockInsts.addInst(exitLabel);

    return true;
}

/// @brief while语句块AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_while(ast_node * node)
{
	ast_node * cond_node = node->sons[0];
    ast_node * stmt_node = node->sons[1];

	// 先创建三个Label
	LabelIRInst * loopEntryLabel = new LabelIRInst(), * loopStmtEntryLabel = new LabelIRInst();
	LabelIRInst * exitLabel = new LabelIRInst();

	// 保存break和continue label旧址，后面要恢复
	LabelIRInst* oldBreakLabel = symtab->currentFunc->breakLabel;
	LabelIRInst* oldContinueLabel = symtab->currentFunc->continueLabel;
	// 添加break和continue出口
	symtab->currentFunc->breakLabel = exitLabel;
	symtab->currentFunc->continueLabel = loopEntryLabel;
	// 给条件语句块添加出口
	cond_node->trueLabel = loopStmtEntryLabel, cond_node->falseLabel = exitLabel;

	// 添加循环开始label
	node->blockInsts.addInst(loopEntryLabel);

    // 条件判断
    ast_node * Cond = ir_visit_ast_node(cond_node);
    if (!Cond) {
        return false;
    }
	node->blockInsts.addInst(Cond->blockInsts);
	// 当孩子节点不是逻辑表达式时，还需要加自己加bool转换和有条件跳转语句
	condPoint2Int(Cond, node);

	node->blockInsts.addInst(loopStmtEntryLabel);

    // 语句
    ast_node * Stmt = ir_visit_ast_node(stmt_node);
    if (!Stmt) {
        return false;
    }
	node->blockInsts.addInst(Stmt->blockInsts);
	node->blockInsts.addInst(new GotoIRInst(loopEntryLabel));
	node->blockInsts.addInst(exitLabel);

	// 恢复break和continue出口
	symtab->currentFunc->breakLabel = oldBreakLabel;
	symtab->currentFunc->continueLabel = oldContinueLabel;

    return true;
}

/// @brief for语句块AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_for(ast_node * node)
{
	ast_node * init_node = node->sons[0];
	ast_node * cond_node = node->sons[1];
    ast_node * update_node = node->sons[2];
    ast_node * stmt_node = node->sons[3];

	// 先创建Label
	LabelIRInst * loopEntryLabel = new LabelIRInst(), * updateLabel = new LabelIRInst();
	LabelIRInst * loopStmtEntryLabel = new LabelIRInst(), * exitLabel = new LabelIRInst();

	// 保存break和continue label旧址，后面要恢复
	LabelIRInst* oldBreakLabel = symtab->currentFunc->breakLabel;
	LabelIRInst* oldContinueLabel = symtab->currentFunc->continueLabel;
	// 添加break和continue出口
	symtab->currentFunc->breakLabel = exitLabel;
	symtab->currentFunc->continueLabel = loopEntryLabel;
	// 给条件语句块添加出口
	cond_node->trueLabel = loopStmtEntryLabel, cond_node->falseLabel = exitLabel;

	symtab->blockDepth++;

	// 初始化语句
    ast_node * Init = ir_visit_ast_node(init_node);
    if (!Init) {
        return false;
    }
	node->blockInsts.addInst(Init->blockInsts);
	// 添加循环开始label
	node->blockInsts.addInst(loopEntryLabel);

    // 条件判断
    ast_node * Cond = ir_visit_ast_node(cond_node);
    if (!Cond) {
        return false;
    }
	node->blockInsts.addInst(Cond->blockInsts);
	// 当孩子节点不是逻辑表达式时，还需要加自己加bool转换和有条件跳转语句
	condPoint2Int(Cond, node);

	node->blockInsts.addInst(updateLabel);
	// 更新语句
	ast_node * Update = ir_visit_ast_node(update_node);
    if (!Update) {
        return false;
    }
	node->blockInsts.addInst(Update->blockInsts);
	node->blockInsts.addInst(new GotoIRInst(loopEntryLabel));

	node->blockInsts.addInst(loopStmtEntryLabel);
    // 循环体
    ast_node * Stmt = ir_visit_ast_node(stmt_node);
    if (!Stmt) {
        return false;
    }
	node->blockInsts.addInst(Stmt->blockInsts);
	node->blockInsts.addInst(new GotoIRInst(updateLabel));
	node->blockInsts.addInst(exitLabel);

	ir_block_var_clear();
	symtab->blockDepth--;

	// 恢复break和continue出口
	symtab->currentFunc->breakLabel = oldBreakLabel;
	symtab->currentFunc->continueLabel = oldContinueLabel;
	return true;
}


/// @brief 关系判断AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_rel(ast_node * node)
{
    ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

	// TODO: 目前将等于/不等于 和 其他关系操作符 的优先级视为相等，如果后面出现(a>3)==(b>1)这种的，要改
	IRInstOperator op = getRelOperator(node->node_type);
	LabelIRInst * trueLabel = node->trueLabel, * falseLabel = node->falseLabel;

    // 左结合，先计算左节点，后计算右节点

    // 左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    Value * resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);
	Value* lval;
	if (left->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, left->val));
		lval = tmp;
	} else {
		lval = left->val;
	}
    node->blockInsts.addInst(right->blockInsts);
	Value* rval;
	if (right->val->type.type == BasicType::TYPE_INT_POINT) {
		Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
		node->blockInsts.addInst(new AssignIRInst(tmp, right->val));
		rval = tmp;
	} else {
		rval = right->val;
	}

	node->blockInsts.addInst(new RelIRInst(op, resultValue, lval, rval));
	node->blockInsts.addInst(new GotoIRInst(resultValue, trueLabel, falseLabel));

	node->val = resultValue;

    return true;
}

/// @brief 与逻辑判断AST节点翻译成线性中间IR
/// @param node AST节点
/// @param trueLabel 真出口
/// @param falseLabel 假出口
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_log_and(ast_node * node)
{
	ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

	LabelIRInst * trueLabel = node->trueLabel, * falseLabel = node->falseLabel;
	// 创建一个 前一个条件判断为真以后 继续判断后一个条件的出口
	LabelIRInst * exitLabel = new LabelIRInst();

	src1_node->trueLabel = exitLabel;
	src1_node->falseLabel = falseLabel;
	src2_node->trueLabel = trueLabel;
	src2_node->falseLabel = falseLabel;

    // 左结合，先计算左节点，后计算右节点

    // 左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);

	// 当孩子节点不是逻辑表达式时，还需要加自己加bool转换和有条件跳转语句
	condPoint2Int(left, node);

	// 插入中间Label
	node->blockInsts.addInst(exitLabel);

    node->blockInsts.addInst(right->blockInsts);

	// 当孩子节点不是逻辑表达式时，还需要加自己加bool转换和有条件跳转语句
	condPoint2Int(right, node);

    return true;
}

/// @brief 或逻辑判断AST节点翻译成线性中间IR
/// @param node AST节点
/// @param trueLabel 真出口
/// @param falseLabel 假出口
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_log_or(ast_node * node) 
{
	ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

	LabelIRInst * trueLabel = node->trueLabel, * falseLabel = node->falseLabel;
	// 创建一个 前一个条件判断为真以后 继续判断后一个条件的出口
	LabelIRInst * exitLabel = new LabelIRInst();

	src1_node->trueLabel = trueLabel;
	src1_node->falseLabel = exitLabel;
	src2_node->trueLabel = trueLabel;
	src2_node->falseLabel = falseLabel;

    // 左结合，先计算左节点，后计算右节点

    // 左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);

	// 当孩子节点不是逻辑表达式时，还需要加自己加bool转换和有条件跳转语句
	condPoint2Int(left, node);

	// 插入中间Label
	node->blockInsts.addInst(exitLabel);

    node->blockInsts.addInst(right->blockInsts);
	// 当孩子节点不是逻辑表达式时，还需要加自己加bool转换和有条件跳转语句
	condPoint2Int(right, node);

    return true;
}

/// @brief 非逻辑判断AST节点翻译成线性中间IR
/// @param node AST节点
/// @param trueLabel 真出口
/// @param falseLabel 假出口
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_log_not(ast_node * node)
{
	ast_node * src_node = node->sons[0];

	LabelIRInst * trueLabel = node->trueLabel, * falseLabel = node->falseLabel;
	// 创建一个 前一个条件判断为真以后 继续判断后一个条件的出口

	src_node->trueLabel = falseLabel;
	src_node->falseLabel = trueLabel;

    ast_node * left = ir_visit_ast_node(src_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);

	// 当孩子节点不是逻辑表达式时，还需要加自己加bool转换和有条件跳转语句
	if (!isRelOrLogOp(left->node_type)) {
		// 当是数组表达式时，要将其转换为i32形式
		Value* lval;
		if (left->val->type.type == BasicType::TYPE_INT_POINT) {
			Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
			node->blockInsts.addInst(new AssignIRInst(tmp, left->val));
			lval = tmp;
		} else {
			lval = left->val;
		}
		node->val = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
		node->blockInsts.addInst(new RelIRInst(IRInstOperator::IRINST_REL_EQ, node->val, lval, symtab->newConstValue((int32_t) 0)));
		// 当其父节点为逻辑节点或者if节点时，还需要加bool转换和有条件跳转语句，因为这些节点上面识别!，会将其视为逻辑节点，不会生成跳转语句
		if (isLogOp(node->parent->node_type) || node->parent->node_type == ast_operator_type::AST_OP_IF || node->parent->node_type == ast_operator_type::AST_OP_WHILE) {
			Value * t1 = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
        	node->blockInsts.addInst(new RelIRInst(IRInstOperator::IRINST_REL_NEQ, t1, node->val, symtab->newConstValue((int32_t) 0)));
			node->blockInsts.addInst(new GotoIRInst(t1, trueLabel, falseLabel));
		}
	}

    return true;
}

/// @brief break AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_break(ast_node * node)
{
	node->blockInsts.addInst(new GotoIRInst(symtab->currentFunc->breakLabel));
	return true;
}


/// @brief continue AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_continue(ast_node * node)
{
	node->blockInsts.addInst(new GotoIRInst(symtab->currentFunc->continueLabel));
	return true;
}

/// @brief 未知节点类型的节点处理
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_default(ast_node * node)
{
    // 未知的节点
    printf("Unkown node(%d)\n", (int) node->node_type);
    return true;
}

/// @brief 根据AST的节点运算符查找对应的翻译函数并执行翻译动作
/// @param node AST节点
/// @return 成功返回node节点，否则返回nullptr
ast_node * IRGenerator::ir_visit_ast_node(ast_node * node)
{
    // 空节点
    if (nullptr == node) {
        return nullptr;
    }

    bool result;

    std::unordered_map<ast_operator_type, ast2ir_handler_t>::const_iterator pIter;
    pIter = ast2ir_handlers.find(node->node_type);
    if (pIter == ast2ir_handlers.end()) {
        // 没有找到，则说明当前不支持
        result = (this->ir_default)(node);
    } else {
        result = (this->*(pIter->second))(node);
    }

    if (!result) {
        // 语义解析错误，则出错返回
        node = nullptr;
    }

    return node;
}

/// @brief 遍历抽象语法树产生线性IR，保存到IRCode中
/// @param root 抽象语法树
/// @param IRCode 线性IR
/// @return true: 成功 false: 失败
bool IRGenerator::run()
{
    ast_node * node;

    // 从根节点进行遍历
    node = ir_visit_ast_node(root);

    return node != nullptr;
}
